package com.woniu.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.domain.Position;
import com.woniu.domain.UserPosition;
import com.woniu.mapper.PositionMapper;
import com.woniu.service.PositionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.service.UserPositionService;
import com.woniu.vo.*;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;

import javax.annotation.Resource;
import java.util.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zyy
 * @since 2021-03-05
 */
@Service
public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements PositionService {

    @Resource
    private PositionMapper positionMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private UserPositionService userPositionService;


    @Override
    public List<Position> deletePositinByCompanyId(Integer companyId) {
        List<Position> positions = positionMapper.lookPositionByCompanyId(companyId);
        return positions;
    }

    @Override
    public List<Position> getHotPositions() {

        //从数据库中查询热点信息
        QueryWrapper<Position> ew = new QueryWrapper<>();
        ew.eq("statusc", "发布");
        List<Position> positions = positionMapper.selectList(ew);

        if (!ObjectUtils.isEmpty(positions)) {
            positions.forEach(record -> {
                //往redis中新增一些数据
                System.out.println(record);
                stringRedisTemplate.opsForHash().put("position1:id:" + record.getPositionId(), "Position1VisitCount", record.getVisitCount().toString());
                stringRedisTemplate.opsForHash().put("position1:id:" + record.getPositionId(), "Position1Hot", record.getHot());
                //用来做排行榜的
                stringRedisTemplate.opsForSet().add("position1:ids", record.getPositionId().toString());
            });
            //全部为发布职位的id
            Set<String> ids = stringRedisTemplate.opsForSet().members("position1:ids");
            //用来做后台管理的比较器
            ArrayList<CompanyPositionSort> managerSorts = new ArrayList<>();
            //用来做流浪量管理的比较器
            ArrayList<CompanyPositionSort> lookSorts = new ArrayList<>();
            //用来存储发布信息的集合
            ArrayList<Position> needsPositions = new ArrayList<Position>();


            //处理平台推送
            ids.forEach(id -> {
                Object position1VisitCount = stringRedisTemplate.opsForHash().get("position1:id:" + id, "Position1VisitCount");
                Object position1Hot = stringRedisTemplate.opsForHash().get("position1:id:" + id, "Position1Hot");
                //处理平台推送的
                if("平台推送".equals(position1Hot.toString())){
                    managerSorts.add(CompanyPositionSort.builder().positionId(Integer.valueOf(id))
                            .statusc(position1Hot.toString())
                            .visitCount(Integer.valueOf(position1VisitCount.toString()))
                            .build());
                    //可以定时更新数据库
                    Position entity = new Position();
                    entity.setPositionId(Integer.valueOf(id));
                    entity.setHot("平台推送");
                    entity.setVisitCount(Integer.valueOf(position1VisitCount.toString()));
                    positionMapper.updateById(entity);
                }else{
                    //处理非平台推送的
                    lookSorts.add(CompanyPositionSort.builder().positionId(Integer.valueOf(id))
                            .statusc(position1Hot.toString())
                            .visitCount(Integer.valueOf(position1VisitCount.toString()))
                            .build());
                    //可以定时更新数据库
                    Position entity = new Position();
                    entity.setPositionId(Integer.valueOf(id));
                    entity.setHot("浏览量推送");
                    entity.setVisitCount(Integer.valueOf(position1VisitCount.toString()));
                    positionMapper.updateById(entity);
                }
            });
            Collections.sort(managerSorts);
            Collections.sort(lookSorts);

            List<String> sortIds = stringRedisTemplate.opsForList().range("positions1:sortId", 0, -1);


            if(!ObjectUtils.isEmpty(sortIds)){

                sortIds.forEach(id->{

                    Position position = positionMapper.selectById(id);
                    if(ObjectUtils.isEmpty(position)){
                        stringRedisTemplate.opsForList().remove("resumes1:sortId",1, id);
                    }

                    Object position1Hot = stringRedisTemplate.opsForHash().get("position1:id:" + id, "Position1Hot");
                    if(position1Hot.toString().equals("平台推送")){
                        return ;
                    }
                    stringRedisTemplate.opsForHash().put("position1:id:" + id, "Position1Hot","非热点" );
                });
            }
            stringRedisTemplate.delete("positions1:sortId");
            int count = 0;
            for (int i = 0; i < managerSorts.size(); i++) {
                if (++count > 5) break;
                needsPositions.add(positionMapper.selectById(managerSorts.get(i).getPositionId()));
                stringRedisTemplate.opsForList().rightPush("positions1:sortId", (managerSorts.get(i).getPositionId().toString()));
            }
            for(int i=0;i<lookSorts.size();i++){
                if (++count > 5)  break;
                needsPositions.add(positionMapper.selectById(lookSorts.get(i).getPositionId()));
                stringRedisTemplate.opsForList().rightPush("positions1:sortId", (lookSorts.get(i).getPositionId().toString()));
            }
            sortIds = stringRedisTemplate.opsForList().range("positions1:sortId", 0, -1);
            needsPositions.clear();
            sortIds.forEach(id->{
                needsPositions.add(positionMapper.selectById(id));
            });

           for(int i=0;i<needsPositions.size();i++){
               if(needsPositions.get(i)==null){
                   needsPositions.remove(i);
               }
           }


            return needsPositions;
        }
        return null;


    }

//    @Resource
//    private RedisTemplate<String,PositionDetailsVo> redisTemplate;

    //根据公司id查询该公司下的所有职位
    @Override
    public List<DataPie> queryPositionByCid(Integer compId) {
        List<DataPie> positions = new ArrayList<>();
        List<Position> positionList = positionMapper.queryPositionByCid(compId);
        for (Position position : positionList) {
            DataPie dataPie = new DataPie();
            dataPie.setName(position.getTname());
            dataPie.setValue(position.getVisitCount());
            positions.add(dataPie);
        }
        return positions;
    }

    //    职位详情页面数据


    @Override
    public PositionDetailsVo jobTitle(Integer positionId) {
//从Redis中查询数据
        ListOperations operations = redisTemplate.opsForList();
        List list = operations.range("cAndp", 0, -1);
        if (ObjectUtils.isEmpty(list)) {
            //Redis中没有数据
            synchronized (this){
                //防止高并发访问时多次访问数据库
                list = operations.range("cAndp", 0, -1);
                if (ObjectUtils.isEmpty(list)) {
                    //redis没有数据，从数据库中查询
                    PositionDetailsVo positionDetailsVo = positionMapper.jobTitle(positionId);
                    //将职位访问量和公司访问量+1
                    positionDetailsVo.setCompanyVisitCount
                            (positionDetailsVo.getCompanyVisitCount()+1);
                    positionDetailsVo.setPositionVisitCount
                            (positionDetailsVo.getPositionVisitCount()+1);
                    if (ObjectUtils.isEmpty(positionDetailsVo)) {
                        return null;
                    }
                    //将其存到Redis中
                    operations.leftPush("cAndp",positionDetailsVo);
                    return positionDetailsVo;
                }
            }
        }
        //Redis中有数据
        //将数据转换为ArrayList
        ArrayList<PositionDetailsVo> details = new ArrayList<>();
        for(Object o:list){
            String s = JSON.toJSONString(o);
            PositionDetailsVo rePosition= JSONObject.parseObject(s,PositionDetailsVo.class);
            details.add(rePosition);
        }
        //判断是否有符合要求的数据
        for (PositionDetailsVo positionDetailsVo : details) {
            if (positionDetailsVo.getPositionId().equals(positionId)) {
                //有要求的数据，将Redis中的本条数据删除
                operations.remove("cAndp",1,positionDetailsVo);
                //将职位访问量和公司访问量+1
                positionDetailsVo.setCompanyVisitCount
                        (positionDetailsVo.getCompanyVisitCount()+1);
                positionDetailsVo.setPositionVisitCount
                        (positionDetailsVo.getPositionVisitCount()+1);
                //将改变后的数据存入Redis
                operations.leftPush("cAndp",positionDetailsVo);
                return positionDetailsVo;
            }
        }

        //没有符合要求的数据，从数据库中查询
        synchronized (this){
            //防止高并发访问时多次访问数据库
            list = operations.range("cAndp", 0, -1);
            //将数据转换为ArrayList
            for(Object o:list){
                String s = JSON.toJSONString(o);
                PositionDetailsVo rePosition= JSONObject.parseObject(s,PositionDetailsVo.class);
                details.add(rePosition);
            }
            for (PositionDetailsVo positionDetailsVo : details) {
                if (positionDetailsVo.getPositionId().equals(positionId)) {
                    //有要求的数据，将Redis中的本条数据删除
                    operations.remove("cAndp",1,positionDetailsVo);
                    //将职位访问量和公司访问量+1
                    positionDetailsVo.setCompanyVisitCount
                            (positionDetailsVo.getCompanyVisitCount()+1);
                    positionDetailsVo.setPositionVisitCount
                            (positionDetailsVo.getPositionVisitCount()+1);
                    //将改变后的数据存入Redis
                    operations.leftPush("cAndp",positionDetailsVo);
                    return positionDetailsVo;
                }
            }
            //没有要求的数据，从数据库查询
            PositionDetailsVo positionDetailsVo = positionMapper.jobTitle(positionId);
            //将职位访问量和公司访问量+1
            positionDetailsVo.setCompanyVisitCount
                    (positionDetailsVo.getCompanyVisitCount()+1);
            positionDetailsVo.setPositionVisitCount
                    (positionDetailsVo.getPositionVisitCount()+1);
            //将其存到Redis中
            operations.leftPush("cAndp",positionDetailsVo);
            return positionDetailsVo;
        }
    }

    //    modifyStatus 点击投递简历按钮
    @Override
    public Integer modifyStatus(Integer positionId,Integer userId) {
//        Integer positionDetailsVo = positionMapper.modifyStatus(positionId, userId);
        int positionDetailsVo = positionMapper.modifyStatus(positionId, userId);

        System.out.println("测试线："+positionDetailsVo);
        if (positionDetailsVo<0) {
            return 0;
        }
        return 1;
    }

    @Override
    public IPage<Position> getPage(PositionVo positionVo, Integer id){
        Page<Position> page=new Page<>(positionVo.getCurrent(),positionVo.getSize());
        QueryWrapper<Position> wrapper = new QueryWrapper<>();
        wrapper.eq("up.uid",id);
        return positionMapper.getPage(page, wrapper);

    }

    @Override
    public IPage conditionPage(PositionVo positionVo,Integer id) {
        Page<Position> page=new Page<>(positionVo.getCurrent(),5);
        QueryWrapper<Position> wrapper=new QueryWrapper<>();
        wrapper.eq("up.uid",id);
        if (!org.springframework.util.ObjectUtils.isEmpty(positionVo.getName())){
            wrapper.like("tname",positionVo.getName());
        }
        return positionMapper.getPage(page, wrapper);

    }

    @Override
//    @CacheEvict(cacheNames = "getPage" , key = "123")
    public Position addPosition(Position position,Integer uid) {
        if (this.save(position)){
            UserPosition userPosition=new UserPosition();
            userPosition.setUid(uid);
            userPosition.setPid(position.getPositionId());
            userPositionService.save(userPosition);
        }
        return position;
    }

    @Override
//    @CacheEvict(cacheNames = "getPage" , key = "123")
    public void updateP(Position position) {
        UpdateWrapper<Position> wrapper = new UpdateWrapper<>();
        wrapper.eq("position_id",position.getPositionId());
        this.update(position, wrapper);
    }

    @Override
    public IPage<Position> statusPage(PositionVo positionVo, Integer uid, String status) {
        Page<Position> page=new Page<>(positionVo.getCurrent(),positionVo.getSize());
        QueryWrapper<Position> wrapper=new QueryWrapper<>();
        wrapper.eq("up.uid",uid);
        wrapper.eq("p.statusc",status);
        return positionMapper.getPage(page, wrapper);
    }


    @Override
    public Position selectP(String id){
            QueryWrapper<Position> wrapper = new QueryWrapper<>();
            wrapper.eq("position_id",id);
        return this.getOne(wrapper);
    }

    @Override
//    @CacheEvict(cacheNames = "getPage" , key = "123")
    public void deleteP(List<String> Ids) {
        Set<String> set = new HashSet<>(Ids);
        set.addAll(Ids);
        System.out.println(set);
        for (String str:set){
            this.removeById(str);
        }
        for (String str:Ids){
            QueryWrapper<UserPosition> wrapper = new QueryWrapper<>();
            wrapper.eq("pid",str);
            userPositionService.remove(wrapper);
        }
    }

    @Override
    public String selectStatus(Integer uid) {
        return positionMapper.selectStatus(uid);
    }
}
